﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;

namespace Hopfield
{
    class PatternHelper
    {
        internal static int[][] GeneratePatternFromImage(Image img)
        {
            var dx = img.Width;
            var dy = img.Height;
            int[][] ret = GetArray<int>(dx, dy);

            using (var b = new Bitmap(img))
            {
                for (int x = 0; x < dx; x++)
                {
                    for (int y = 0; y < dy; y++)
                    {
                        ret[x][y] = (int) (b.GetPixel(x, y).GetBrightness() > 0.5f ? 1 : -1);
                    }
                }
            }

            return ret;
        }

        /// <summary>
        /// Writes a pattern as a png-image to a given filelocation
        /// </summary>
        /// <param name="directory">Directory where the output should be saved</param>
        /// <param name="file">Filename without extension</param>
        /// <param name="pattern">the pattern to save</param>
        internal static void WritePatternToImageFile(String directory, String file, int[][] pattern)
        {
            var dx = pattern.Count();
            var dy = pattern[0].Count();

            var bitmap = new Bitmap(dx, dy);

            for (int x = 0; x < dx; x++)
            {
                for (int y = 0; y < dy; y++)
                {
                    bitmap.SetPixel(x,y, pattern[x][y] == 1 ? Color.White : Color.Black);
                }
            }

            bitmap.Save(Path.Combine(directory, file + ".png"), ImageFormat.Png);
        }

        internal static T[][] GetArray<T>(int dx, int dy)
        {
            var ret = new T[dx][];
            for (int i = 0; i < dx; i++)
            {
                ret[i] = new T[dy];
            }
            return ret;
        }

        internal static int[][] ReadInputPattern(string dir)
        {
            return Directory.EnumerateFiles(dir).Where(IsImageFile)
                .Select(file =>
                            {
                                Console.WriteLine("Using input: {0}", file);
                                return Image.FromFile(file);
                            })
                .Select(img => GeneratePatternFromImage(img))
                .FirstOrDefault();
        }

        internal static List<int[][]> ReadPatterns(string dir)
        {
            return Directory.EnumerateFiles(dir).AsParallel().Where(IsImageFile)
                .Select(file => {Console.WriteLine("Using pattern: {0}", file); return Image.FromFile(file); })
                .Select(img => GeneratePatternFromImage(img))
                .ToList();
        }

        internal static bool IsImageFile(string file)
        {
            var f = file.ToLower();
            return f.EndsWith(".bmp") || f.EndsWith(".jpg") || f.EndsWith(".png");
        }
    }
}
